import axios from 'axios';
import { ElNotification, ElMessageBox } from 'element-plus';
import sysConfig from "@/config";
import tool from '@/utils/tool';
import router from '@/router';
import errorCode from '@/utils/errorCode'
import qs from "qs";
import store from '@/store/index.js';

// import { addPendingRequest, removePendingRequest } from './request/cancelRepeatRquest'; // 取消重复请求
// import { againRequest } from '../request/requestAgainSend'; // 请求重发
import { requestInterceptor as cacheReqInterceptor, responseInterceptor as cacheResInterceptor } from './request/requestCache.js';



axios.defaults.baseURL = process.env.VUE_APP_API_BASEURL
axios.defaults.timeout = sysConfig.TIMEOUT

// HTTP request 拦截器
axios.interceptors.request.use(
	(config) => {
		let token = tool.cookie.get("TOKEN");
		if(token){
			config.headers[sysConfig.TOKEN_NAME] = sysConfig.TOKEN_PREFIX + token
		}
		if(!sysConfig.REQUEST_CACHE && config.method == 'get'){
			config.params = config.params || {};
			// config.params['_'] = new Date().getTime();
		}
		// get请求映射params参数
		if (config.method === "get" && config.params) {
			let url = `${config.url}?`;
			for (const propName of Object.keys(config.params)) {
			  const value = config.params[propName];
			  const part = `${encodeURIComponent(propName)}=`;
			  // 新增过滤空值
			  if (value !== null && typeof value !== "undefined" && value !== "") {
				if (typeof value === "object") {
				  for (const key of Object.keys(value)) {
					const params = `${propName}[${key}]`;
					const subPart = `${encodeURIComponent(params)}=`;
					url += `${subPart + encodeURIComponent(value[key])}&`;
				  }
				} else {
				  url += `${part + encodeURIComponent(value)}&`;
				}
			  }
			}
			url = url.slice(0, -1);
			config.params = {};
			config.url = url;
			
			
		  }
		if(config.method === "get" && config.cache){
			// addPendingRequest(config); // 把当前请求信息添加到pendingRequest对象中
			cacheReqInterceptor(config);//  请求缓存
			
		}
		Object.assign(config.headers, sysConfig.HEADERS)
		return config;
	},
	(error) => {
		return Promise.reject(error);
	}
);

//FIX 多个API同时401时疯狂弹窗BUG
let MessageBox_401_show = false

// HTTP response 拦截器
axios.interceptors.response.use(
	
	(response) => {
		let t = store.state.common.requestI18n
		// 响应正常时候就从pendingRequest对象中移除请求
		// removePendingRequest(response);
		cacheResInterceptor(response);
		const code = response.data.code || 200;
		let responseMsg = response.data.msg
		if(t){
			responseMsg = t[responseMsg]
		}
		const message = responseMsg||response.msg||response.data.msg || errorCode['default']
		// 二进制数据则直接返回
		if(response.request.responseType ===  'blob' || response.request.responseType ===  'arraybuffer'){
			return response.data
		  }
		if (code== 404) {
			ElNotification.error({
				title: '请求错误',
				message: message
			});
		} else if (code == 500) {
			ElNotification.error({
				title: '请求错误',
				message: message || "Status:500，服务器发生错误！"
			});
		} else if (code == 401 || code == 402) {
			if(!MessageBox_401_show){
				MessageBox_401_show = true
				ElMessageBox.confirm(message, '无权限访问', {
					type: 'error',
					closeOnClickModal: false,
					center: true,
					confirmButtonText: '重新登录',
					beforeClose: (action, instance, done) => {
						MessageBox_401_show = false
						// tool.data.clear()
						tool.data.remove('USER_INFO')
						tool.data.remove('SELECTEMAIL')
						tool.data.remove('SELECTEMAILUSERID')
						tool.data.remove('MENU')
						tool.data.remove('DEFAULTEMAIL')
						tool.data.remove('PERMISSIONS')
						tool.cookie.remove('TOKEN')
						done()
					}
				}).then(() => {
					router.replace({path: '/login'});
				}).catch(() => {})
			}
		} else if (code === 601) {
			ElNotification.error({ message: message, type: 'warning' })
			return Promise.reject('error')
		  } else if (code !== 200) {
			ElNotification.error({ title: message })
			return Promise.reject('error')
		  } else {
			return response.data
		  }
	},
	(error) => {
		let t = store.state.common.requestI18n
		// removePendingRequest(error.config || {});
		// 请求缓存处理方式
        if (axios.isCancel(error) && error.message.data && error.message.data.config.cache) {
            return Promise.resolve(error.message.data.data); // 返回结果数据			
        }
		let { message } = error;
		if (message == "Network Error") {
		message = "后端接口连接异常";
		} else if (message.includes("timeout")) {
		message = "系统接口请求超时";
		} else if (message.includes("Request failed with status code")) {
		//message = "系统接口" + message.substr(message.length - 3) + "异常";
		//console.log(i18n,this.$t)
		if(error.response.data.i18nArgs){
			console.log(error.response.data.msg,t[error.response.data.msg])
			let formattedMsg = error.response.data.i18nArgs.reduce((prevMsg, currentValue, index) => {
				return prevMsg.replace("{" + index + "}", currentValue);
			}, t[error.response.data.msg]);
			message = formattedMsg
		}else{
			message = t[error.response.data.msg] || error.response.data.msg
		}

		}
		ElNotification.error({ message: message, duration: 5 * 1000 })
		return Promise.reject(error.response);
	}
);

var http = {

	/** get 请求
	 * @param  {string} url 接口地址
	 * @param  {object} params 请求参数
	 * @param  {object} config 参数
	 */
	get: function(url, params={}, config={}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'get',
				url: url,
				params: params,
				...config
			}).then((response) => {
				resolve(response);
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** post 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	post: function(url, data={}, config={}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'post',
				url: url,
				data: data,
				...config
			}).then((response) => {
				resolve(response);
			}).catch((error) => {
				reject(error);
			})
		})
	},
	postForm: function(url, data={}, config={}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'post',
				url: url,
				data:qs.stringify(data),
				...config
			}).then((response) => {
				resolve(response);
			}).catch((error) => {
				reject(error);
			})
		})
	},
	/** put 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	put: function(url, data={}, config={}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'put',
				url: url,
				data: data,
				...config
			}).then((response) => {
				resolve(response);
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** patch 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	patch: function(url, data={}, config={}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'patch',
				url: url,
				data: data,
				...config
			}).then((response) => {
				resolve(response);
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** delete 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	delete: function(url, data={}, config={}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'delete',
				url: url,
				data:qs.stringify(data),
				...config
			}).then((response) => {
				resolve(response);
			}).catch((error) => {
				reject(error);
			})
		})
	},
	pDelete: function(url, data={}, config={}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'delete',
				url: url,
				data: data,
				...config
			}).then((response) => {
				resolve(response);
			}).catch((error) => {
				reject(error);
			})
		})
	},
	/** delete 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	 deleteForm: function(url, data={}, config={}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'delete',
				url: url,
				params: data,
				...config
			}).then((response) => {
				resolve(response);
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** jsonp 请求
	 * @param  {string} url 接口地址
	 * @param  {string} name JSONP回调函数名称
	 */
	jsonp: function(url, name='jsonp'){
		return new Promise((resolve) => {
			var script = document.createElement('script')
			var _id = `jsonp${Math.ceil(Math.random() * 1000000)}`
			script.id = _id
			script.type = 'text/javascript'
			script.src = url
			window[name] =(response) => {
				resolve(response)
				document.getElementsByTagName('head')[0].removeChild(script)
				try {
					delete window[name];
				}catch(e){
					window[name] = undefined;
				}
			}
			document.getElementsByTagName('head')[0].appendChild(script)
		})
	}
}

export default http;
